#pragma once

// 1. setsid();
// 2. setsid(), 调用进程，不能是组长！我们怎么保证自己不是组长呢？
// 3. 守护进程a. 忽略异常信号 b. 0,1,2要做特殊处理 c. 进程的工作路径可能要更改 / 根目录
#include <unistd.h>
#include <cstring>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "log.hpp"
#include "err.hpp"

void Daemon()
{
    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, SIG_IGN);

    if (fork() > 0)
        exit(0); // 关闭父线程，剩下的由子进程代理运行
    pid_t id = setsid();
    if (id < 0)
    {
        LogMessage(Fatal, "deamon error, error: %d, reason: %s", errno, strerror(errno));
        exit(DEAMON_ERR);
    }

    int fb = open("/dev/null", O_RDONLY); // 将 0,1,2 等描述符送进 “数据黑洞”，防止因为读写问题导致线程起不来
    if(fb < 0)
    {
        LogMessage(Fatal, "open error, error: %d, reason: %s", errno, strerror(errno));
        exit(OPEN_ERR);
    }
    dup2(fb, 0);
    dup2(fb, 1);
    dup2(fb, 2);
    close(fb);
}